

#pragma once

#include "zacgi.h"

#pragma pack (push, 8)

class UcGiLightTraits : public UcGiNonEntityTraits
{
public:
    UCRX_DECLARE_MEMBERS(UcGiLightTraits);
    virtual void setOn(bool on) = 0;
    virtual bool isOn() const = 0;
};

class UcGiShadowParameters : public UcRxObject
{
public:
    UCRX_DECLARE_MEMBERS(UcGiShadowParameters);

    UcGiShadowParameters();
    virtual ~UcGiShadowParameters();

    bool operator==(const UcGiShadowParameters& params) const;
    virtual void setShadowsOn(bool on);
    virtual bool shadowsOn() const;
    
	enum ShadowType {
        kShadowsRayTraced = 0,
        kShadowMaps,
        kAreaSampled
    };
    
	virtual void setShadowType(ShadowType typ);
    virtual ShadowType shadowType() const;
    virtual bool setShadowMapSize(ZSoft::UInt16 sz);
    virtual ZSoft::UInt16 shadowMapSize() const;
    virtual bool setShadowMapSoftness(ZSoft::UInt8 soft);
    virtual ZSoft::UInt8 shadowMapSoftness() const;
    virtual bool setShadowSamples(ZSoft::UInt16 samples);
    virtual ZSoft::UInt16 shadowSamples() const;
    virtual void setShapeVisibility(bool visible);
    virtual bool shapeVisibility() const;
    
	enum ExtendedLightShape {
        kLinear = 0,
        kRectangle,
        kDisk,
        kCylinder,
        kSphere
    };
    
	virtual bool setExtendedLightShape(ExtendedLightShape shape);
    virtual ExtendedLightShape extendedLightShape() const;
    virtual bool setExtendedLightLength(double length);
    virtual double extendedLightLength() const;
    virtual bool setExtendedLightWidth(double width);
    virtual double extendedLightWidth() const;
    virtual bool setExtendedLightRadius(double radius);
    virtual double extendedLightRadius() const;

protected:
	bool				mShadowsOn;
	ShadowType			mShadowType;
	ZSoft::UInt16		mShadowMapSize;
	ZSoft::UInt8		mShadowMapSoftness;
    ZSoft::UInt16       mShadowSamples;
    bool                mbShapeVisibility;
    ExtendedLightShape  mExtLightShape;
    double              mExtLightLength;
    double              mExtLightWidth;
    double              mExtLightRadius;
};

class UcGiLightAttenuation : public UcRxObject
{
public:
    UCRX_DECLARE_MEMBERS(UcGiLightAttenuation);

    UcGiLightAttenuation();
    virtual ~UcGiLightAttenuation();

    bool operator==(const UcGiLightAttenuation& atten) const;
    
	enum AttenuationType {
        kNone = 0,
        kInverseLinear,
        kInverseSquare
    };

    virtual void setAttenuationType(AttenuationType typ);
    virtual AttenuationType attenuationType() const;
    virtual void setUseLimits(bool on);
    virtual bool useLimits() const;
    virtual void setLimits(double startlim, double endlim);
    virtual double startLimit() const;
    virtual double endLimit() const;

private:
    AttenuationType mAttenType;
    bool            mUseAttenLimits;
    double          mAttenStartLimit;
    double          mAttenEndLimit;
};

class UcGiSkyParameters : public UcRxObject
{
public:
    UCRX_DECLARE_MEMBERS(UcGiSkyParameters);

    UcGiSkyParameters();
    virtual ~UcGiSkyParameters();

    bool operator==(const UcGiSkyParameters& params) const;
    void setIllumination(bool enable)   { return setIlluminationImp(enable); }
    bool illumination() const { return illuminationImp(); }
    bool setIntensityFactor(double intensity)   { return setIntensityFactorImp(intensity); }
    double intensityFactor() const { return intensityFactorImp(); }
    bool setHaze(double haze) { return setHazeImp(haze); }
    double haze() const { return hazeImp(); }
    bool setHorizonHeight(double height) { return setHorizonHeightImp(height); }
    double horizonHeight() const    { return horizonHeightImp(); }
    bool setHorizonBlur(double blur) { return setHorizonBlurImp(blur); }
    double horizonBlur() const { return horizonBlurImp(); }
    void setGroundColor(const UcCmColor& color) { return setGroundColorImp(color); }
    UcCmColor groundColor() const { return groundColorImp(); }
    void setNightColor(const UcCmColor& color) { setNightColorImp(color); }
    UcCmColor nightColor() const    { return nightColorImp(); }
    void setAerialPerspective(bool apply) { setAerialPerspectiveImp(apply); }
    bool aerialPerspective() const { return aerialPerspectiveImp(); }
    bool setVisibilityDistance(double distance) { return setVisibilityDistanceImp(distance); }
    double visibilityDistance() const { return visibilityDistanceImp(); }
    bool setDiskScale(double scale) { return setDiskScaleImp(scale); }
    double diskScale() const { return diskScaleImp(); }
    bool setGlowIntensity (double intensity) { return setGlowIntensityImp(intensity); }
    double glowIntensity() const { return glowIntensityImp(); }
    bool setDiskIntensity(double intensity) { return setDiskIntensityImp(intensity); }
    double diskIntensity() const { return diskIntensityImp(); }
    bool setSolarDiskSamples(ZSoft::UInt16 samples) { return setSolarDiskSamplesImp(samples); }
    ZSoft::UInt16 solarDiskSamples() const { return solarDiskSamplesImp(); }
    bool setSunDirection(const UcGeVector3d& sundir) { return setSunDirectionImp(sundir); }
    const UcGeVector3d& sunDirection() const { return sunDirectionImp(); }
    bool setRedBlueShift (double redBlueShift)  { return setRedBlueShiftImp(redBlueShift); }
    double redBlueShift  (void) const           { return redBlueShiftImp(); }
    bool setSaturation (double saturation)      { return setSaturationImp(saturation); }
    double saturation (void) const              { return saturationImp(); }

protected:
    virtual void setIlluminationImp (bool enable);
    virtual bool illuminationImp (void) const;

    virtual bool setIntensityFactorImp (double intensity);
    virtual double intensityFactorImp () const;

    virtual bool setHazeImp (double haze);
    virtual double hazeImp (void) const;

    virtual bool setHorizonHeightImp        (double height);
    virtual double horizonHeightImp (void) const;

    virtual bool setHorizonBlurImp (double blur);
    virtual double horizonBlurImp () const;

    virtual void setGroundColorImp (const UcCmColor& color);
    virtual UcCmColor groundColorImp () const;

    virtual void setNightColorImp (const UcCmColor& color);
    virtual UcCmColor nightColorImp () const;

    virtual void setAerialPerspectiveImp (bool apply);
    virtual bool aerialPerspectiveImp () const;

    virtual bool setVisibilityDistanceImp (double distance);
    virtual double visibilityDistanceImp () const;

    virtual bool setDiskScaleImp (double scale);
    virtual double diskScaleImp () const;

    virtual bool setGlowIntensityImp (double intensity);
    virtual double glowIntensityImp () const;

    virtual bool setDiskIntensityImp (double intensity);
    virtual double diskIntensityImp () const;

    virtual bool setSolarDiskSamplesImp (ZSoft::UInt16 samples);
    virtual ZSoft::UInt16 solarDiskSamplesImp (void) const;

    virtual bool  setSunDirectionImp (const UcGeVector3d& sundir);
    virtual const UcGeVector3d& sunDirectionImp (void) const;

    virtual bool setRedBlueShiftImp  (double redBlueShift);
    virtual double  redBlueShiftImp (void) const;

    virtual bool setSaturationImp (double saturation);
    virtual double  saturationImp (void) const;

private:
    bool            mStatus;
    double          mIntensityFactor;
    double          mHaze;
    double          mHorizonHeight;
    double          mHorizonBlur;
    UcCmColor       mGroundColor;
    UcCmColor       mNightColor;
    bool            mAerialPerspective;
    double          mVisibilityDistance;
    double          mDiskScale;
    double          mGlowIntensity;
    double          mDiskIntensity;
    ZSoft::UInt16   mSolarDiskSamples;
    UcGeVector3d    mSunDirection;
    double          mRedBlueShift;
    double          mSaturation;
};

class UcGiStandardLightTraits : public UcGiLightTraits
{
public:
    UCRX_DECLARE_MEMBERS(UcGiStandardLightTraits);
    virtual void setIntensity(double inten) = 0;
    virtual double intensity() const = 0;
    virtual void setLightColor(const UcCmColor& color) = 0;
    virtual UcCmColor lightColor() const = 0;
    virtual void setShadowParameters(const UcGiShadowParameters& params) = 0;
    virtual void shadowParameters(UcGiShadowParameters& params) const = 0;
};

class UcGiPointLightTraits : public UcGiStandardLightTraits
{
public:
    UCRX_DECLARE_MEMBERS(UcGiPointLightTraits);
    virtual void setPosition(const UcGePoint3d& pos) = 0;
    virtual UcGePoint3d position() const = 0;
    virtual void lightAttenuation(UcGiLightAttenuation& atten) const = 0;
    virtual void setAttenuation(const UcGiLightAttenuation& atten) = 0;
    virtual void setPhysicalIntensity(double physicalIntensity) = 0;
    virtual double physicalIntensity() const = 0;
    virtual void setLampColor (const UcGiColorRGB& rgbColor) = 0;
    virtual void lampColor (UcGiColorRGB& rgbColor) const = 0;
    virtual void setHasTarget (bool bHasTarget) = 0;
    virtual bool hasTarget (void) const = 0;
    virtual void setTargetLocation(const UcGePoint3d& loc) = 0;
    virtual UcGePoint3d targetLocation() const = 0;
};

class UcGiSpotLightTraits : public UcGiStandardLightTraits
{
public:
    UCRX_DECLARE_MEMBERS(UcGiSpotLightTraits);
    virtual void setPosition(const UcGePoint3d& pos) = 0;
    virtual UcGePoint3d position() const = 0;
    virtual void setTargetLocation(const UcGePoint3d& loc) = 0;
    virtual UcGePoint3d targetLocation() const = 0;
    virtual bool setHotspotAndFalloff(double hotspot, double falloff) = 0;
    virtual double hotspot() const = 0;
    virtual double falloff() const = 0;
    virtual void lightAttenuation(UcGiLightAttenuation& atten) const = 0;
    virtual void setAttenuation(const UcGiLightAttenuation& atten) = 0;
};

class UcGiSpotLightTraits2 : public UcGiSpotLightTraits
{
public:
    UCRX_DECLARE_MEMBERS(UcGiSpotLightTraits2);
    virtual void setPhysicalIntensity(double physicalIntensity) = 0;
    virtual double physicalIntensity() const = 0;
    virtual void setLampColor (const UcGiColorRGB& rgbColor) = 0;
    virtual void lampColor (UcGiColorRGB& rgbColor) const = 0;
    virtual void setShadowParameters(const UcGiShadowParameters& params) = 0;
    virtual void shadowParameters(UcGiShadowParameters& params) const = 0;
};

class UcGiDistantLightTraits : public UcGiStandardLightTraits
{
public:
    UCRX_DECLARE_MEMBERS(UcGiDistantLightTraits);
    virtual void setLightDirection(const UcGeVector3d& vec) = 0;
    virtual UcGeVector3d lightDirection() const = 0;
    virtual void setIsSunlight(bool isSunlight) = 0;
    virtual bool isSunlight() const = 0;
    virtual void setPhysicalIntensity(double physicalIntensity) = 0;
    virtual double physicalIntensity() const = 0;
    virtual void setLampColor (const UcGiColorRGB& rgbColor) = 0;
    virtual void lampColor (UcGiColorRGB& rgbColor) const = 0;
    virtual void setSkyParameters(const UcGiSkyParameters& params) = 0;
    virtual void skyParameters(UcGiSkyParameters& params) const = 0;
};

class UcGiWebLightTraits : public UcGiPointLightTraits
{
public:
    UCRX_DECLARE_MEMBERS(UcGiWebLightTraits);
    enum WebFileType
    {
        kTypeC = 1,
        kTypeB = 2,
        kTypeA = 3
    };

    enum WebSymmetry
    {
        kNoSymmetry = 0,
        kSingleSymmetry = 1,
        kDoubleSymmetry = 2,
        kAxialSymmetry = 3,
    };

    virtual void setWebFile(const ZTCHAR* webFile) = 0;
    virtual void webFile(UcString& webFile) const = 0;
    virtual void setWebRotation(UcGeVector3d rotation) = 0;
    virtual void webRotation(UcGeVector3d& rotation) const = 0;
    virtual void setWebFlux(double flux) const = 0;
    virtual double webFlux() const = 0;
    virtual void setWebFileType (WebFileType type) = 0;
    virtual WebFileType webFileType (void) const = 0;
    virtual void setWebSymmetry (WebSymmetry symmetry) = 0;
    virtual WebSymmetry webSymmetry (void) const = 0;
    virtual void setWebHorzAng90to270 (bool bIs90to270) = 0;
    virtual bool webHorzAng90to270 (void) const = 0;
};

#pragma pack (pop)
